package com.smsc.headend.task.engine.handler.impl.collection.builder;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.SystemClock;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.smsc.headend.common.enums.DeviceType;
import com.smsc.headend.common.utils.CosemUtils;
import com.smsc.headend.module.data.entity.RdScheduleReadParamValue;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.protocol.cosem.util.ByteUtils;
import com.smsc.headend.module.task.consts.TaskKafkaTopic;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.task.engine.service.CosemXmlService;
import com.smsc.headend.task.engine.service.RdScheduleReadParamValueService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;
import java.util.Map;

@Slf4j
@Component
public class ScheduleReadGeneralHandler implements ScheduleReadBuilder {

    @Autowired
    CosemXmlService cosemXmlService;

    @Autowired
    RdScheduleReadParamValueService rdScheduleReadParamValueService;

    @Autowired
    KafkaTemplate kafkaTemplate;

    @Override
    public void handleScheduleReadResult(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult, Boolean dcuDataItemFlag, Map<String, Object> param) {

        Object referObj = param.get("referValue");
        String referValue = null == referObj ? null : String.valueOf(param.get("referValue"));
//        String descrb = String.valueOf(map.get("descrb"));
        String dcuIdStr = String.valueOf(param.get("dcuId"));
        String dataItemIdStr = String.valueOf(param.get("dataItemId"));
//        String paramIdStr = (String) map.get("paramId");
//        Long paramId = Long.valueOf(paramIdStr);

        CosemData cosemData = (CosemData) deviceData;
        Object data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
        if ("OctetString".equalsIgnoreCase(cosemData.getType())) {
            if (CosemUtils.isDateTimeString(Convert.toStr(data))) {
                data = DateFormatUtils.format(CosemUtils.parseOctStringDataTime(Convert.toStr(data)), "yyyy-MM-dd HH:mm:ss");
            } else if (CosemUtils.isLocalDate(Convert.toStr(data))) {
                data = CosemUtils.parseOctStringDate(Convert.toStr(data));
            } else if (CosemUtils.isLocalTime(Convert.toStr(data))) {
                data = CosemUtils.parseOctStringTime(Convert.toStr(data));
            } else {
                data = new String(ByteUtils.hexStringToByte(Convert.toStr(data)), Charset.forName("utf-8"));
            }
        }

        String dataStr = String.valueOf(data);

        RdScheduleReadParamValue rdScheduleReadParamValue = new RdScheduleReadParamValue();
        rdScheduleReadParamValue.setDeviceId(dcuDataItemFlag ? Long.valueOf(dcuIdStr) : task.getMeterId());
        rdScheduleReadParamValue.setDeviceType(dcuDataItemFlag ? DeviceType.DCU.getId() :
                DeviceType.METER.getId());
        rdScheduleReadParamValue.setDeviceValue(dataStr);
        rdScheduleReadParamValue.setTv(Long.valueOf(Math.toIntExact(SystemClock.now() / 1000)));
        rdScheduleReadParamValue.setTvCreate(Long.valueOf(Math.toIntExact(SystemClock.now() / 1000)));
        if (!"null".equals(referValue)) {
            rdScheduleReadParamValue.setReferValue(referValue);
        }
        rdScheduleReadParamValue.setSubDataItemId(Long.valueOf(dataItemIdStr));
        rdScheduleReadParamValue.setSuggestResult(getSuggest(referValue, dataStr));
        rdScheduleReadParamValueService.save(rdScheduleReadParamValue);

        // 同步拉合闸状态至mdm：当 dataItemIdStr 为  1020700001103
        if ("1020700001103".equals(dataItemIdStr)) {
            JSONObject obj = JSONUtil.createObj();
            obj.put("meterId", task.getMeterId());
            obj.put("value", dataStr);
            obj.put("tv", SystemClock.now() / 1000);
            kafkaTemplate.send(TaskKafkaTopic.CLIENT_CONTROL_STATE, JSONUtil.toJsonStr(obj).getBytes(Charset.forName("utf-8")));
        }
    }
}
